import streamlit as st
from tools.DBUtil import DBUtil
from datetime import datetime,timedelta
from tools.verification import *
from scripts.vpShere_manager import VsphereManager
from tools.email_sender import EmailSender
import re

from tools.SecureCookieManager import SecureCookieManager

##########################################################获取页面所需要的数据##################################################################
cookie_manager = SecureCookieManager()
# 从数据库获取平台选项，并缓存到session_state中
if "platform_options" not in st.session_state:
    st.session_state.platform_options = [""]
    platform_list = DBUtil.select_all("SELECT servername FROM config_vsphere;")
    for platform in platform_list:
        st.session_state.platform_options.append(platform["servername"])

if "vspheremanager" not in st.session_state:
    st.session_state.vspheremanager = None

if "vmmodel_options" not in st.session_state:
    st.session_state.vmmodel_options = [""]

if "platform_selected" not in st.session_state:
    st.session_state.platform_selected = ""

# 当云虚拟机平台选择后，查询该平台的模板列表，并设置cookies
def get_vmmodel_options(platform):
    vmmodel_options = [""]
    # 从查询中获取
    server = DBUtil.select_one("SELECT * FROM config_vsphere WHERE servername=%s;",(platform,))
    serverip = server["serverip"]
    serverusername = server["username"]
    serverpassword = server["passwd"]
    serverdatacentername = server["datacentername"]
    servermodelfoldername = server["modelfoldername"]
    
    st.session_state.vspheremanager = VsphereManager(serverip,serverusername,serverpassword,serverdatacentername,servermodelfoldername)
    if st.session_state.vspheremanager.connect():
        vmmodel_options = st.session_state.vspheremanager.list_vms_in_folder(servermodelfoldername)  # 显示模板列表
        if 'user_options' in st.session_state:  # 如果存在用户列表，则删除此缓存，在下次时重新获取用户列表
            del st.session_state.user_options
    # st.session_state.vspheremanager.disconnect()  # 断开连接
    return vmmodel_options

def is_valid_vmname(usergroup,vmname):
    if st.session_state.vspheremanager:
        vmobj = st.session_state.vspheremanager.find_vm_by_folder(usergroup,vmname)
    return vmobj is not None

# 执行创建虚拟机操作
def create_vm_page(vmname, create_message, is_approval=False, create_code=None):
    # 1.解析虚拟机名称，从数据库中获取云虚拟机平台配置信息
    try:
        match_ids = re.findall(r"_(\d+)\(", vmname)
        id = match_ids[-1]  # 取最后一个匹配的结果
    except:
        create_message.error("虚拟机名称错误，请重新输入")
        return

    apply_record = DBUtil.select_one("SELECT * FROM vm_apply_his WHERE id=%s;",(id,))
    platform = apply_record["platform"]
    vmmodel = apply_record["vmmodel"]
    usergroup = apply_record["usergroup"]
    useto = apply_record["useto"]
    useendtime = apply_record["useendtime"]
    applyreason = apply_record["applyreason"]
    username = apply_record["username"]
    oaname = DBUtil.select_one("SELECT oamail FROM user WHERE username=%s;",(username,))["oamail"].split("@")[0]
    applytime = apply_record["applytime"]
    approvalcode = apply_record["approvalcode"]
    approvalstatus = apply_record["approvalstatus"]
    user_id = DBUtil.select_one("SELECT id FROM user WHERE username=%s;",(username,))["id"]
    vsphere_id = DBUtil.select_one("SELECT id FROM config_vsphere WHERE servername=%s;",(platform,))["id"]

    if approvalstatus==1:
        create_message.error("该虚拟机已创建，请勿重复创建!")
        return
    
    if is_approval and create_code!=approvalcode:
        create_message.error("创建码与虚拟机不匹配，请重新输入")
        return
    
    # 3.连接云虚拟机平台，克隆虚拟机
    if st.session_state.vspheremanager:
        clone_result = st.session_state.vspheremanager.clone_vm_to_folder_with_streamlit(vmmodel,vmname,usergroup,create_message)
        try:
            create_message.info(f"正在查找创建的虚拟机对象 {vmmodel}...")
            st.session_state.vspheremanager.add_permission_to_vm(vmname,"sznari.com",[oaname],-2089829018)  # 添加权限
        except:
            create_message.warning(f"虚拟机创建成功, 但添加权限失败, 请在'云虚拟机管理'中手动添加权限")
        if clone_result:
            # 写入数据库记录，记录虚拟机的创建信息
            if 'created_data' in st.session_state:
                del st.session_state.created_data
                del st.session_state.server_options
            DBUtil.uid_db("INSERT INTO vm_list (vmname, function, applytime, applyreason, endtime, owner_id, vsphere_id) VALUES (%s, %s, %s, %s, %s, %s, %s)",(vmname, useto, applytime, applyreason, useendtime, user_id, vsphere_id))
            DBUtil.uid_db("UPDATE vm_apply_his SET approvalstatus=1 WHERE id=%s;",(id,))
    else:
        create_message.error("连接云虚拟机平台失败，请检查配置信息")       
# ==================================================页面内容控制========================================================
st.title("云虚拟机申请")

is_need_approval = DBUtil.select_one("SELECT approval from system_config;")["approval"]  # 获取系统配置中是否需要审批
group_result = DBUtil.select_all("SELECT * FROM config_group;")
group_eamil_dict = {group["groupname"]:group["adminemail"] for group in group_result}
group_options = [""] + [group["groupname"] for group in group_result]


if is_need_approval:
    st.subheader("一、请填写并提交申请信息")
    buttun_name = "提交申请"
else:
    buttun_name = "创建"

# 1.从数据库中获取云虚拟机平台配置信息
platform_options = st.session_state.platform_options
platform = st.selectbox("1.选择云虚拟机平台", platform_options, index=0,key="platform")
if platform and platform != st.session_state.platform_selected:
    st.session_state.platform_selected = platform
    st.session_state.vmmodel_options = get_vmmodel_options(platform)
# 2.选择了云虚拟机后连接云虚拟机平台，获取模板列表
model_type = st.radio("2.选择云虚拟机模板: ", ["模板库模板","自定义虚拟机模板"], index=0,key="model_type",horizontal=True)
if model_type=="模板库模板":
    vmmodel = st.selectbox("模板库模板", st.session_state.vmmodel_options, index=0,key="vmmodel",label_visibility="collapsed")  
else:
    # 3.1选择组别、模板名称进行搜索
    vmmodel = st.text_input("自定义虚拟机模板名称",key="vmmodel",placeholder="请输入所属组下存在的完整虚拟机名称",label_visibility="collapsed")
   
 # 3.选择组别、用途、使用截止时间
col3, col4, col5 = st.columns([3,3,3])
usergroup = col3.selectbox("组别", group_options, index=0,key="group")
useto_options = ["","开发测试", "稳定运行", "程序打包"]
useto = col4.selectbox("用途", useto_options, index=0,key="useto")
useendtime = col5.date_input("使用截止期限", value=datetime.now()+timedelta(days=180), key="useendtime",help="默认180天")   # 设置了此时间将用于到期后，邮件通知用户续期或删除释放虚拟机
# 4.填写申请原因
applyreason = st.text_area("申请原因", max_chars=200,key="applyreason")

# 显示创建按钮1
create_vm_button = st.button(buttun_name)
create_message = st.empty()

if create_vm_button:
    if platform and vmmodel and usergroup and useto and applyreason and useendtime:
        if(model_type=="模板库模板" or (model_type=="自定义虚拟机模板" and is_valid_vmname(usergroup,vmmodel))):
            # 1.插入到申请记录中去
            username = cookie_manager.get_cookie("username")
            applytime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            useendtime = useendtime.strftime("%Y-%m-%d %H:%M:%S")
            approvalcode = generate_verification_code()
            record_data = DBUtil.select_one("SELECT MAX(id) as id from vm_apply_his")["id"]
            record_data = record_data if record_data else 0
            record_id = record_data +1
            vmname = vmmodel + "_" + str(record_id) + f"({useto}-{username})"
            DBUtil.uid_db("INSERT INTO vm_apply_his (vmname,platform,vmmodel,usergroup,useto,useendtime,applyreason,username,applytime,approvalstatus,approvalcode) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",(vmname,platform,vmmodel,usergroup,useto,useendtime,applyreason,username,applytime,0,approvalcode))
            
            # 2.执行创建方法
            print(f"虚拟机名称:{vmname},申请时间:{applytime},申请原因:{applyreason},使用截止时间:{useendtime}")
            # 调用创建虚拟机函数,判断是否需要审批
            if is_need_approval:
                create_message.success(f"创建申请单成功,虚拟机名称为{vmname},请联系{group_eamil_dict[usergroup]}获取创建码,并在下面输入相关信息进行创建...")
                # 发送邮件通知管理员
                html_body = f"""
                <p>尊敬的领导：</p>
                    <p>您好! 用户: {username} 正在申请创建云虚拟机,请审核信息并<strong>回复创建码</strong>给用户, 以完成创建。</p>
                    <p>申请信息: </p>
                    <ul>
                        <li>云虚拟机平台: {platform}</li>
                        <li>虚拟机名称: {vmname}</li>
                        <li>申请原因: {applyreason}</li>
                        <li>使用截止时间: {useendtime}</li>
                        <li>创建码: <strong>{approvalcode}</strong></li>
                    </ul>
                """
                EmailSender().send_email(group_eamil_dict[usergroup],"虚拟主机审批申请",html_body)
            else:
                create_message.success("添加创建虚拟机任务成功,请等待虚拟机创建完成...")
                create_vm_page(vmname,create_message)  # 显示创建虚拟机页面 
        else:
            create_message.error("自定义虚拟机在所属组下不存在或错误，请重新输入")
    else:
        create_message.error("请填写完整信息")

if is_need_approval:
    st.subheader("二、开始创建虚拟机")
    with st.form(key="create_form_approval",border=False):
        username = cookie_manager.get_cookie("username")
        waiting_create_list = DBUtil.select_all("SELECT vmname FROM vm_apply_his WHERE approvalstatus=0 AND username=%s;",(username,))
        wating_create_options = [""]
        if waiting_create_list:
            wating_create_options = wating_create_options + [record["vmname"] for record in waiting_create_list]

        col1,col2,col3 = st.columns([1,1,1])
        vmname = col1.selectbox("选择待创建虚拟机", wating_create_options, index=0,key="vmname")
        create_code = col2.text_input("创建码",key="approvalcode")
        col3.markdown("<p style='height:12px;'></p>", unsafe_allow_html=True)
        create_button = col3.form_submit_button("创建")
        create_message2 = st.empty()

    if create_button:
        if vmname and create_code:
            create_vm_page(vmname,create_message2,True,create_code)  # 显示创建虚拟机页面
        else:
            create_message2.error("请填写完整信息")

